package com.golxen.framework.common.server.cross.sync.message;


import com.golxen.framework.GameProtocol;
import com.golxen.framework.PBPacket.PBPacket;
import com.golxen.framework.PBPacket.PBPacketUtils;
import com.golxen.framework.common.BuiltinPlugin;
import com.golxen.framework.netty.session.cross.CrossAgentLinkedSet;
import com.golxen.framework.common.server.game.sync.message.GameSyncCmdService;
import com.golxen.framework.common.server.game.sync.message.SyncMessageDispatcher;
import com.golxen.framework.common.server.game.sync.message.SyncResponse;
import com.golxen.framework.common.server.game.sync.message.SyncResultProcessor;
import com.golxen.framework.manager.TempMgr;
import com.golxen.protojava.SyncMessage;
import com.google.protobuf.ByteString;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.InvalidProtocolBufferException;

import java.util.concurrent.CompletableFuture;

public class CrossSyncServiceMgr extends TempMgr {

	private static final GameSyncCmdService syncMessageService = new GameSyncCmdService();
	private static final SyncMessageDispatcher dispatcher = new SyncMessageDispatcher();

	public boolean reload() throws Exception {
		initServiceCommand();
		return true;
	}

	/**
	 * 初始化
	 */
	public static void initServiceCommand() {

	}

	public static GameSyncCmdService getSyncMessageService() {
		return syncMessageService;
	}

	public static CompletableFuture<SyncResponse> sendToGameServer(long forwardServerId, int code, int activityId,
																   long userId, GeneratedMessage.Builder<?> requestBuilder, GeneratedMessage.Builder<?> responseBuilder) {

		long serverId = BuiltinPlugin.getCrossServerId();
		SyncResultProcessor resultProcessor = sendMsgSync(serverId, forwardServerId, userId, code,
				GameProtocol.S_GAME_SERVICE_HANDLER, activityId, requestBuilder, responseBuilder);
		PBPacket request = resultProcessor.getRequest();
		boolean sendPacket = CrossAgentLinkedSet.send(forwardServerId, 0, request);
		CompletableFuture<SyncResponse> completableFuture = resultProcessor.getCompletableFuture();
		if (sendPacket) { // 信令成功发出，则等待响应，否则，立即失败
			return completableFuture;
		}
		completableFuture.completeExceptionally(new RuntimeException("send msg " + code + " 2 serverID=" + forwardServerId + " failed!"));
		return completableFuture;
	}

	public static SyncResultProcessor sendMsgSync(long rawServerId, long forwardServerId, long userId, int code, int sCode,
												  int activityId, GeneratedMessage.Builder<?> requestBuilder, GeneratedMessage.Builder<?> responseBuilder) {
		SyncMessage.Request.Builder builder = SyncMessage.Request.newBuilder();
		builder.setCmdCode(code);
		if (requestBuilder != null) {
			ByteString byteString = requestBuilder.build().toByteString();
			builder.setDataBytes(byteString);
		}
		builder.setActivityId(activityId);
		builder.setRawServerId(rawServerId);
		builder.setForwardServerId(forwardServerId);
		builder.setSenderId(userId);
		SyncResultProcessor resultProcessor = dispatcher.pending(builder);
		resultProcessor.setResponseBuilder(responseBuilder);
		PBPacket buildMessage = PBPacketUtils.buildMessage(sCode, 0, builder);
		resultProcessor.setRequest(buildMessage);
		return resultProcessor;
	}

	public static void receiveMsgHandler(PBPacket packet) {
		try {
			SyncMessage.Response response = SyncMessage.Response.parseFrom(packet.getBytes());
			dispatcher.receive(response);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

	}

	public static void scheduleClean() {
		dispatcher.scheduleCleanResultProcessor();
	}

}
